package com.dtsheep.elasticsearch.es.controller;

import com.dtsheep.elasticsearch.es.client.ElasticsearchClientUtil;
import com.dtsheep.elasticsearch.es.document.UserDocument;
import com.dtsheep.elasticsearch.es.repository.UserDocumentRepository;
import com.dtsheep.elasticsearch.es.service.UserDocumentService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * UserController
 *
 * <p>
 * </p>
 *
 * @author chuanbai
 * @date 2024/5/24
 */
@RestController
@RequestMapping("/user")
public class UserDocumentController {

    @Resource
    private UserDocumentService userDocumentService;

    /**
     * 根据id查询es文档
     */
    @GetMapping("/query/{id}")
    public ResponseEntity queryById(@PathVariable("id") Long id){
       return new ResponseEntity(userDocumentService.queryById(id), HttpStatus.OK);
    }

    /**
     * 查询所有文档
     */
    @GetMapping("/query/all")
    public ResponseEntity queryAll(){
        return new ResponseEntity(userDocumentService.queryAll(), HttpStatus.OK);
    }

    /**
     * 添加文档
     *
     * 没有给定id时候会自动随机生成id
     * eg.6nCwzI8B9psJNreVHWXM
     * 添加已经存在的id时会进行文档覆盖
     *
     */
    @PostMapping("/insert")
    public ResponseEntity insert(@RequestBody UserDocument userDocument){
        return new ResponseEntity(userDocumentService.insert(userDocument), HttpStatus.OK);
    }

    /**
     * 批量添加文档
     *
     * 没有给定id时候会自动随机生成id
     * eg.6nCwzI8B9psJNreVHWXM
     * 添加已经存在的id时会进行文档覆盖
     *
     */
    @PostMapping("/insert/batch")
    public ResponseEntity insertBatch(@RequestBody List<UserDocument> userDocument){
        return new ResponseEntity(userDocumentService.insertBatch(userDocument), HttpStatus.OK);
    }

    /**
     * 根据文档对象删除文档
     *
     * 全部字段都要匹配才能删掉
     *
     */
    @PostMapping("/delete")
    public ResponseEntity deleteByEntity(@RequestBody UserDocument userDocument){
        return new ResponseEntity(userDocumentService.deleteByEntity(userDocument), HttpStatus.OK);
    }

    /**
     * 根据文档id删除文档
     *
     * 文档id没有的就不会删除
     *
     */
    @PostMapping("/delete/{id}")
    public ResponseEntity deleteById(@PathVariable Long id){
        return new ResponseEntity(userDocumentService.deleteById(id), HttpStatus.OK);
    }

    /**
     * 模糊搜索
     *
     *  文档对象的id字段必传！！！，pageable不能为空！！！！！
     *  integer类型的不能模糊查询！！！
     *
     */
//    @PostMapping("/search")
//    public ResponseEntity search(@RequestParam("sex") String sex){
//        return new ResponseEntity(userDocumentService.search(sex), HttpStatus.OK);
//    }

    /**
     * page进行分页
     *
     * Pageable接口的实现类：PageRequest分页对象
     *
     *  Sort.Direction.DESC：降序
     */
    @PostMapping("/page/desc")
    public ResponseEntity findAllProductsSortedAndPaged() {
        int page = 0;
        int size = 1;
        String sortBy = "age";
        return new ResponseEntity(userDocumentService.findAllProductsSortedAndPaged(page, size, sortBy, Sort.Direction.DESC), HttpStatus.OK);
    }

    /**
     * 条件搜索
     */
    @PostMapping("/search")
    public List<UserDocument> search(){
        return userDocumentService.searchTest();
    }

    @Resource
    private RestHighLevelClient client;
    @Resource
    private ObjectMapper objectMapper;

    /**
     * 滚动查询
     */
    @GetMapping("/roll")
    public List<UserDocument> rollSearch() throws IOException {

        SearchRequest searchRequest = new SearchRequest("user");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        searchSourceBuilder.size(100); // 设置每次返回的文档数量
        searchRequest.scroll(TimeValue.timeValueSeconds(1)); // 设置滚动时间窗口为1秒
        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        List<UserDocument> designDocuments = new ArrayList<>();

        while (true) {
            for (SearchHit hit : searchResponse.getHits().getHits()) {
                // 将每个搜索命中转换为设计文档对象并添加到列表中
                UserDocument designDocument = objectMapper.readValue(hit.getSourceAsString(), UserDocument.class);
                designDocuments.add(designDocument);
            }

            // 检查是否还有数据需要检索
            String scrollId = searchResponse.getScrollId();
            SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
            scrollRequest.scroll(TimeValue.timeValueSeconds(1));
            searchResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT);

            if (searchResponse.getHits().getHits().length == 0) {
                // 所有数据都已经检索完毕
                break;
            }
        }

        System.out.println(designDocuments);
        return designDocuments;
    }
}